﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace CreatingObjects3d
{
    [Serializable()]
    public class Objeto
    {
        //Atributos de clase protected para ser heredados por las clases hijas.
        protected String nombreObjeto;
        protected String tipoObjeto;

        protected Color colorObjeto;
        protected Color colorInterior;
        protected Color colorReflejo;
        protected float reflejoLuzAmbiental;
        protected float brillo;
        protected float transparencia;

        protected float posicionX;
        protected float posicionY;
        protected float posicionZ;

        protected char ejeRotacion;
        protected float anguloRotacion;

        protected float escalaX;
        protected float escalaY;
        protected float escalaZ;

        protected String rutaImagen;
        protected String rutaImgaenProyecto;
        protected Boolean repetirImagenHorizontal;
        protected Boolean repetirImagenVertical;


        #region Metodos Set
        /// <summary>
        /// Asigna el color del objeto en formato RGB.
        /// </summary>
        /// <param name="vR"></param>
        /// <param name="verde"></param>
        /// <param name="azul"></param>
        public void setColorObjeto(int R, int G, int B)
        {
            colorObjeto = System.Drawing.Color.FromArgb(R, G, B);
        }

        /// <summary>
        /// Asigna el color interior del objeto en formato RGB.
        /// </summary>
        /// <returns></returns>
        public int[] getColor()
        {
            int[] arrayColores = new int[3];
            arrayColores[0] = colorObjeto.R;
            arrayColores[1] = colorObjeto.G;
            arrayColores[2] = colorObjeto.B;
            return arrayColores;
        }

        /// <summary>
        /// Introduce el color que regleja el objeto en formato RGB.
        /// </summary>
        /// <param name="Red"></param>
        /// <param name="Green"></param>
        /// <param name="Blue"></param>
        public void setColorReflejado(int R, int G, int B)
        {
            colorReflejo = System.Drawing.Color.FromArgb(R, G, B);

        }

        /// <summary>
        /// Introduce el color interior del objeto en formato RGB.
        /// </summary>
        /// <param name="Red"></param>
        /// <param name="Green"></param>
        /// <param name="Blue"></param>
        public void setColorInterior(int R, int G, int B)
        {
            colorInterior = System.Drawing.Color.FromArgb(R, G, B);
        }

        /// <summary>
        /// Introduce la posición del objeto dentro del espacio, tomando como referencia 0 0 0.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        public void setPosicion(float x, float y, float z)
        {
            posicionX = x;
            posicionY = y;
            posicionZ = z;
        }

        /// <summary>
        /// Introduce la escala al objeto.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        public void setEscala(float x, float y, float z)
        {
            escalaX = x;
            escalaY = y;
            escalaZ = z;
        }

        #endregion Metodos Set

        #region Metodos Get
        /// <summary>
        /// Devuelve el color del objeto en modo RGB.
        /// </summary>
        /// <returns></returns>
        public int[] getColorObjeto()
        {
            int[] arrayColores = new int[3];
            arrayColores[0] = colorObjeto.R;
            arrayColores[1] = colorObjeto.G;
            arrayColores[2] = colorObjeto.B;
            return arrayColores;
        }

        /// <summary>
        /// Devuelve el color interior del objeto en modo RGB.
        /// </summary>
        /// <returns></returns>
        public int[] getColorInterior()
        {
            int[] arrayColores = new int[3];
            arrayColores[0] = colorInterior.R;
            arrayColores[1] = colorInterior.G;
            arrayColores[2] = colorInterior.B;
            return arrayColores;
        }

        /// <summary>
        /// Devuelve el color que refleja el objeto en modo RGB.
        /// </summary>
        /// <returns></returns>
        public int[] getColorReflejado()
        {
            int[] arrayColores = new int[3];
            arrayColores[0] = colorReflejo.R;
            arrayColores[1] = colorReflejo.G;
            arrayColores[2] = colorReflejo.B;
            return arrayColores;
        }

        /// <summary>
        /// Devuelve la posición del objeto dentro del espacio, referenciado al punto 0 0 0.
        /// </summary>
        /// <returns></returns>
        public float[] getPosicion()
        {
            float[] arrayPosicion = new float[3];
            arrayPosicion[0] = posicionX;
            arrayPosicion[1] = posicionY;
            arrayPosicion[2] = posicionZ;
            return arrayPosicion;
        }

        /// <summary>
        /// Devuelve un array con la escala del objeto.(x, y, z)
        /// </summary>
        /// <returns></returns>
        public float[] getEscala()
        {
            float[] arrayEscala = new float[3];
            arrayEscala[0] = escalaX;
            arrayEscala[1] = escalaY;
            arrayEscala[2] = escalaZ;
            return arrayEscala;
        }

        /// <summary>
        /// Devuelve el tipo del objeto.
        /// </summary>
        /// <returns></returns>
        public String getTipoObjeto()
        {
            return tipoObjeto;
        }               

        #endregion Metodos Get

        #region Metodos Set y Get de C#

        /// <summary>
        /// Asigna o devuelve el nombre del objeto.
        /// </summary>
        /// <returns></returns>
        public String NombreObjeto
        {
            get { return this.nombreObjeto; }
            set { this.nombreObjeto = value; }
        }

        /// <summary>
        /// Asigna o devuelve el valor de reflejo de la luz ambiental por el objeto.
        /// </summary>
        /// <returns></returns>
        public float ReflejoLuz
        {
            get { return this.reflejoLuzAmbiental; }
            set { this.reflejoLuzAmbiental = value; }
        }

        /// <summary>
        /// Asigna o devuelve el valor de brillo del objeto.
        /// </summary>
        /// <returns></returns>
        public float Brillo
        {
            get { return this.brillo; }
            set { this.brillo = value; }
        }

        /// <summary>
        /// Asigna o devuelve el valor de transparencia del objeto.
        /// </summary>
        /// <returns></returns>
        public float Transparencia
        {
            get { return this.transparencia; }
            set { this.transparencia = value; }
        }

        /// <summary>
        /// Introduce o devuelve el eje de rotación del objeto.(x, y o z).
        /// </summary>
        /// <param name="eje"></param>
        public char EjeDeRotacion
        {
            get { return ejeRotacion; }
            set { ejeRotacion = value; }
        }

        /// <summary>
        /// Asigna o devuelve el angulo de rotación del objeto.
        /// </summary>
        /// <returns></returns>
        public float AnguloRotacion
        {
            get { return anguloRotacion; }
            set { anguloRotacion = value; }
        }

        /// <summary>
        /// Asigna o devuelve la ruta de la imagen del objeto.
        /// </summary>
        /// <returns></returns>
        public String Imagen
        {
            get { return rutaImagen; }
            set
            {
                rutaImagen = value;
            }
        }

        /// <summary>
        /// Asigna o devuelve la ruta original de la imagen para su uso en el proyecto.
        /// </summary>
        public String RutaImgagenOriginal
        {
            get { return rutaImgaenProyecto; }
            set
            {
                rutaImgaenProyecto = value;
            }
        }

        /// <summary>
        /// Asigna o devuelve el valor de la condición de repetición de imagen en horizontal.
        /// </summary>
        /// <returns></returns>
        public Boolean RepetirImagenHorizontal
        {
            get { return repetirImagenHorizontal; }
            set { repetirImagenHorizontal = value; }
        }

        /// <summary>
        /// Asigna o devuelve el valor de la condición de repetición de imagen en vertical.
        /// </summary>
        /// <returns></returns>
        public Boolean RepetirImagenVertical
        {
            get { return repetirImagenVertical; }
            set { repetirImagenVertical = value; }
        }

        #endregion Metodos Set y Get de C#
    }
}

/* COLOR **********************************

Shape{   
   appearance Appearance{   
      material Material{   
         diffuseColor           color_RGB   
         emissiveColor        color_RGB   
         specularColor        color_RGB  
         ambientIntensity   valor   
         transparency         valor   
         shininess               valor   
      }   
   }   
   geometry ...   
} 
 
diffuseColor:
    El campo diffuseColor representa  lo que la mayoría de los usuarios llamarían como el color del objeto.  
  
emissiveColor:
     El campo emissiveColor se utiliza para fijar el color del brillo del objeto, cuando dicho objeto necesite ser visible en la oscuridad. 
     De esta forma se consigue un efecto en donde la figura representada parece iluminada desde el interior mediante una luz de un determinado color. 
     La configuración por defecto de este campo es el negro, ya que la mayoría de los objetos normalmente no brillan.  
 
specularColor:
     El campo specularColor es un parámetro avanzado que permite indicar qué color de luz refleja el objeto. Por ejemplo, una cama roja no refleja un color rojo, pero una olla rojiza si puede reflejar su color.  
 
ambientIntensity:
     Este campo es otro parámetro avanzado que indica la cantidad de luz ambiental (producida por los diferentes focos de luz del escenario virtual) es reflejada por el objeto.
     Toma valores en coma flotante entre 0.0 y 1.0.  
 
shininess:
     El campo shininess controlan el brillo de un objeto. Toma valores en coma flotante entre 0.0 y 1.0.  
  
transparency:
     El campo transparency indica el nivel de transparencia del objeto. Toma valores en coma flotante entre 0.0 y 1.0, siendo el 1.0 el nivel máximo de transparencia (objeto invisible) y el 0.0 el nivel mínimo (objeto totalmente opaco).  
El valor por defecto es el 0.0. 
 */

/*POSICION, ROTACION Y ESCALA *******************************
Transform{  
   translation  Eje_X  Eje_Y  Eje_Z  
   rotation      Eje_X  Eje_Y  Eje_Z  Ángulo  
   scale          Eje_X  Eje_Y  Eje_Z  
   children[...]  
} 

translation:
El campo translation permite indicar la posición del origen del nuevo sistema de coordenadas perteneciente al grupo dentro del sistema de coordenadas de nodo que lo engloba (nodo padre). 
A través del siguiente ejemplo esta idea quedará más clara: 

rotation:
El campo rotation nos permite girar el sistema de coordenadas del grupo alrededor de uno de los ejes del sistema de coordenadas del nodo padre. 
Para ello, además de indicar sobre que eje se desea realizar el giro, se ha de hacer referencia al grado de inclinación de dicho giro (en radianes). 

scale:
A través del campo scale podemos aumentar o reducir el tamaño de los ejes del sistema de coordenadas del grupo utilizando factores de escala que 
toman como referencia los ejes de coordenadas del sistema del nodo padre. De esta forma aumentamos o disminuimos el tamaño de los objetos que se crean.

 */

/*IMAGEN EN EL OBJETO *************************
Shape {    
    appearance Appearance {    
         material ...    
         texture ImageTexture{
                    url     "direccion_URL"   
                    repeatS valor_lógico   
                    repeatT valor_lógico   
            } 
    }    
    geometry ...    
}
url:
 El campo url contiene la dirección URL del fichero gráfico que se va a usar como textura. Los formatos gráficos que admite VRML son jpeg,gig y png.

repeatS y repeatT:
  La coordenada horizontal se denominada S y la coordenada vertical T. El lado inferior de la imágen se corresponde con el eje S y el lado izquierdo con el eje T. 
  La esquina inferior izquierda de la imagen, según este sistema de coordenadas, vendría dada por el punto (S=0,T=0) y la esquina superior derecha por (S=1,T=1).  
  Los campos repeatS y repeatT determinan como envuelve la textura en las direcciones S y T. Si repeatS es TRUE, la textura se repite (cada vez que S=1) en la dirección S 
  hasta cubrir la superficie del objeto. Si repeatS es FALSE, la textura se adapta a toda la superficie del objeto a lo largo de la dirección S, sin tener en cuenta el valor 
  de las coordenadas S y T. El campo repeatT haría lo mismo sobre el eje T. 
 */
